/*******************************************************************************
 * Copyright (c) 2014-8-25 @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a>.
 * All rights reserved.
 *
 * Contributors:
 *     <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> - initial API and implementation
 ******************************************************************************/
package com.foreveross.project.projectonline.jfinal.tx;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.iff.infra.util.FCS;
import org.iff.infra.util.Logger;
import org.iff.infra.util.RequestHelper;
import org.iff.infra.util.RequestHelper.RequestResult;

import com.foreveross.project.projectonline.jfinal.plugin.ResourceKit;

/**
 * @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> 
 * @since 2014-8-25
 */
public class AfterTxThreadLocal {

	private final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

	private static AfterTxThreadLocal me = new AfterTxThreadLocal();

	public static AfterTxThreadLocal me() {
		return me;
	}

	public Map<String, Object> put(String key, Object value) {
		Map<String, Object> map = null;
		try {
			Logger.debug(FCS.get("[AfterTxThreadLocal.put][{0}][{1}]", key, value));
			map = threadLocal.get();
			if (map == null) {
				threadLocal.set(new HashMap<String, Object>());
				map = threadLocal.get();
			}
			if (StringUtils.isBlank(key) || value == null) {
				return map;
			}
			Object o = map.get(key);
			if (o == null) {
				map.put(key, value);
			} else if (o instanceof Set) {
				((Set) o).add(value);
			} else {
				Set<Object> list = new HashSet<Object>();
				list.add(o);
				list.add(value);
				map.put(key, list);
			}
		} catch (Exception e) {
			Logger.debug(FCS.get("[AfterTxThreadLocal.put][ERROR][{0}][{1}]", key, value), e);
		}
		return map;
	}

	public <T> T get(String key) {
		Map<String, Object> map = threadLocal.get();
		if (map == null) {
			return null;
		}
		return (T) map.get(key);
	}

	public void doUpdateElasticSearch() {
		try {
			Map<String, Object> map = threadLocal.get();
			if (map == null || map.isEmpty()) {
				return;
			}
			String addIndexUrl = ResourceKit.getValue("es.index.add.url");
			for (Entry<String, Object> entry : map.entrySet()) {
				if ("PROJECT".equals(entry.getKey())) {
					Object o = entry.getValue();
					if (o instanceof String) {
						addProjectToElasticSearch(addIndexUrl, o);
					} else if (o instanceof Set) {
						Set<Object> list = (Set<Object>) o;
						for (Object obj : list) {
							if (obj instanceof String) {
								addProjectToElasticSearch(addIndexUrl, obj);
							}
						}
					}
				} else if ("USER".equals(entry.getKey())) {
					Object o = entry.getValue();
					if (o instanceof String) {
						addUserToElasticSearch(addIndexUrl, o);
					} else if (o instanceof Set) {
						Set<Object> list = (Set<Object>) o;
						for (Object obj : list) {
							if (obj instanceof String) {
								addUserToElasticSearch(addIndexUrl, obj);
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void addProjectToElasticSearch(String addIndexUrl, Object obj) {
		addIndexUrl = FCS.get(addIndexUrl, "tb_project.main", (String) obj).toString();
		Logger.debug(FCS.get("[AfterTxThreadLocal.addProjectToElasticSearch][tb_project.main][{0}][{1}]", addIndexUrl,
				obj));
		RequestResult result = RequestHelper.get(addIndexUrl, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
		if (result.isError()) {
			Logger.error(FCS.get("[AfterTxThreadLocal.addProjectToElasticSearch][tb_project.main][{0}][{1}]",
					addIndexUrl, result.getBody()));
		}
	}

	private void addUserToElasticSearch(String addIndexUrl, Object obj) {
		addIndexUrl = FCS.get(addIndexUrl, "tb_user.main", (String) obj).toString();
		Logger.debug(FCS.get("[AfterTxThreadLocal.addUserToElasticSearch][tb_user.main][{0}][{1}]", addIndexUrl, obj));
		RequestResult result = RequestHelper.get(addIndexUrl, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
		if (result.isError()) {
			Logger.error(FCS.get("[AfterTxThreadLocal.addUserToElasticSearch][tb_user.main][{0}][{1}]", addIndexUrl,
					result.getBody()));
		}
	}
}
